package com.chml.controller;

import com.chml.dto.*;
import com.chml.exception.FailCallException;
import com.chml.params.AddMaternityParam;
import com.chml.params.DeleteMaternityParam;
import com.chml.params.GetMaternityDetailParam;
import com.chml.params.MaternityListParam;
import com.chml.pojo.Evaluation;
import com.chml.service.EvaluationService;
import com.chml.service.MaternityService;
import com.chml.service.NursingService;
import com.chml.service.UserService;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 与月嫂相关的操作类，包括月嫂信息的增删改查
 */
@Controller
@RequestMapping("/api")
public class MaternityController {
    @Resource
    private MaternityService maternityService;
    @Resource
    private UserService userService;
    @Resource
    private EvaluationService evaluationService;
    @Resource
    private NursingService nursingService;
    private static Logger logger = LogManager.getRootLogger();

    private String error_message = "后台错误，请联系系统管理员";

    /**
     * 根据过滤条件及排序规则返回符合要求的月嫂列表
     *
     * @param filterInfo
     * @param response
     * @return
     */
    @RequestMapping(value = "/yuesao/list", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getMaternityList(@RequestBody MaternityListParam filterInfo, HttpServletResponse response) {
        logger.log(Level.DEBUG, "getMaternityList function");
        Map<String, Object> result = new HashMap<>();
        try {
            List<MaternityInfoDTO> maternityList = maternityService.getMaternityList(filterInfo, "");
            int total_count = maternityService.getMaternityListCount(filterInfo, "");
            result.put("success", true);
            result.put("msg", "获取信息成功");
            MaternityListMessageDTO listMessageDTO = new MaternityListMessageDTO();
            listMessageDTO.setRecords(maternityList);
            listMessageDTO.setTotal_count(total_count);
            listMessageDTO.setRecords_count(maternityList.size());
            result.put("data", listMessageDTO);
        } catch (Exception e) {
            logger.error("SomeThing is wrong:\n", e);
            result.put("success", false);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    /**
     * 获取某个昵称的月嫂列表
     *
     * @param name
     * @param filterInfo
     * @param response
     * @return
     */
    @RequestMapping(value = "/yuesao/{name}/list", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getNameList(@PathVariable String name, @RequestBody MaternityListParam filterInfo, HttpServletResponse response) {
        logger.log(Level.DEBUG, "getNameList function");
        Map<String, Object> result = new HashMap<>();
        try {
            List<MaternityInfoDTO> maternityList = maternityService.getMaternityList(filterInfo, name);
            int total_count = maternityService.getMaternityListCount(filterInfo, name);
            result.put("success", true);
            result.put("msg", "获取信息成功");
            MaternityListMessageDTO listMessageDTO = new MaternityListMessageDTO();
            listMessageDTO.setRecords(maternityList);
            listMessageDTO.setTotal_count(total_count);
            listMessageDTO.setRecords_count(maternityList.size());
            result.put("data", listMessageDTO);
        } catch (Exception e) {
            logger.error("SomeThing is wrong:\n", e);
            result.put("success", false);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    /**
     * 删除一个或多个月嫂信息
     *
     * @param idList
     * @param response
     * @return
     */
    @RequestMapping(value = "/yuesao/delete", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> deleteMaternity(@RequestBody DeleteMaternityParam idList, HttpServletResponse response) {
        logger.log(Level.DEBUG, "deleteMaternity function");
        Map<String, Object> result = new HashMap<>();
        try {
            maternityService.deleteMaternity(idList);
            result.put("success", true);
            result.put("msg", "删除成功");
        } catch (Exception e) {
            logger.error("SomeThing is wrong:\n", e);
            result.put("success", false);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    /**
     * 获取某个月嫂的详细信息
     *
     * @param id
     * @param maternityDetailParam
     * @param response
     * @return
     */
    @RequestMapping(value = "/yuesao/{id}/detail", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getMaternityDetail(@PathVariable int id, @RequestBody GetMaternityDetailParam maternityDetailParam, HttpServletResponse response) {
        logger.log(Level.DEBUG, "getMaternityDetail function");
        Map<String, Object> result = new HashMap<>();
        try {
            MaternityDetailDTO maternityInfo = maternityService.getMaternityDetail(id, maternityDetailParam.getUid(), maternityDetailParam.getAccess_token());
            result.put("success", true);
            result.put("msg", "获取成功");
            result.put("data", maternityInfo);
        } catch (Exception e) {
            logger.error("SomeThing is wrong:\n", e);
            result.put("success", false);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    /**
     * 根据月嫂信息添加月嫂
     *
     * @param maternityInfo
     * @param response
     * @return
     */
    @RequestMapping(value = "/yuesao/detail", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> addMaternity(@RequestBody AddMaternityParam maternityInfo, HttpServletResponse response) {
        logger.log(Level.DEBUG, "AddMaternity function");
        Map<String, Object> result = new HashMap<>();
        try {
            int id = maternityService.addMaternity(maternityInfo);
            result.put("success", true);
            result.put("msg", "月嫂添加成功");
            AddMaternityDTO maternityDTO = new AddMaternityDTO();
            maternityDTO.setId(id);
            result.put("data", maternityDTO);
        } catch (Exception e) {
            logger.error("SomeThing is wrong:\n", e);
            result.put("success", false);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    /**
     * 保存修改后的月嫂信息
     *
     * @param mid
     * @param maternityInfo
     * @param response
     * @return
     */
    @RequestMapping(value = "/yuesao/{mid}/detail", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> updateMaternityDetail(@PathVariable int mid, @RequestBody AddMaternityParam maternityInfo, HttpServletResponse response) {
        logger.log(Level.DEBUG, "updateMaternityDetail function");
        Map<String, Object> result = new HashMap<>();
        try {
            maternityService.updateMaternity(mid, maternityInfo);
            result.put("success", true);
            result.put("msg", "修改成功");
        } catch (Exception e) {
            logger.error("SomeThing is wrong:\n", e);
            result.put("success", false);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{mid}/base", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getMaternityBaseInfo(@PathVariable int mid) {
        logger.debug("getMaternityBaseInfo method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", maternityService.getBaseInfo(mid));
        } catch (FailCallException e) {
            result.put("success", false);
            result.put("code", e.getCode());
            result.put("msg", e.getMessage());
            logger.error(e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("code", 400);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/grade/points", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getMaternityGradePoints(@PathVariable("id") int id) {
        logger.debug("getMaternityGradePoints method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", evaluationService.getGradePointsByMid(id));
        } catch (Exception e) {
            result.put("success", false);
            result.put("code", 400);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{mid}/record", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> addServiceRecord(@PathVariable("mid") int mid,
                                                @RequestHeader(name = "access_token") String accessToken,
                                                @RequestBody ServiceRecordDto record) {
        logger.debug("addServiceRecord method call");
        Map<String, Object> result = new HashMap<>();
        try {
            if (!userService.isValidRequest(accessToken))
                throw new FailCallException("无效的token", 101);
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            evaluationService.addRecord(mid, record);
        } catch (FailCallException e) {
            result.put("success", false);
            result.put("code", e.getCode());
            result.put("msg", e.getMessage());
            logger.error(e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("code", 400);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    /**
     * 根据月嫂ID和服务记录（评价）ID获取详情
     *
     * @param mid 月嫂ID
     * @param gid 服务记录（评价）ID获，选填，不填时返回可查到的最早的记录
     * @return 服务记录（评价）
     */
    @RequestMapping(value = "/yuesao/{mid}/record/{gid}", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getServiceRecord(@PathVariable int mid,
                                                @PathVariable(required = false) Integer gid) {
        logger.debug("getServiceRecord method call");
        Map<String, Object> result = new HashMap<>();
        try {
            Evaluation record = evaluationService.getRecord(gid, mid);
            if ((record == null && gid != null) || (record != null && record.getMid() != mid))
                throw new FailCallException("月嫂与服务记录不匹配", 150);
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", record);
        } catch (FailCallException e) {
            result.put("success", false);
            result.put("code", e.getCode());
            result.put("msg", e.getMessage());
            logger.error(e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("code", 400);
            result.put("msg", error_message);
            logger.log(Level.ERROR, e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{mid}/records", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getServiceRecords(@PathVariable int mid,
                                                 @RequestParam(defaultValue = "0") int page,
                                                 @RequestParam(defaultValue = "10") int perPage) {
        logger.debug("getServiceRecord method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            List<ServiceRecordDto> records = evaluationService.getRecordsByMid(mid, page, perPage, "create_date desc");
            Map<String, Object> data = new HashMap<>();
            data.put("total", evaluationService.getGradeCount(mid));
            data.put("count", records.size());
            data.put("records", records);
            result.put("data", data);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("success", false);
            result.put("code", 400);
            result.put("msg", e);
            logger.error(e);
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/nursing/base", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getBaseNursingExpInfo(@PathVariable("id") int id) {
        logger.debug("getBaseNursingExpInfo method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", nursingService.getBaseNursingExpInfoByMid(id));
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/certificates", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getCertificates(@PathVariable("id") int id) {
        logger.debug("getCertificates method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", maternityService.getCertificates(id));
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/photo/working", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getWorkingPhotos(@PathVariable("id") int id) {
        logger.debug("getCertificates method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", maternityService.getWorkingPhoto(id));
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/record/{year}/months", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getServingMonthsInYear(@PathVariable("id") int id, @PathVariable("year") int year) {
        logger.debug("getServingMonthsInYear method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", evaluationService.getServingMonthsInYear(id, year));
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/records/{year}/{month}", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getServingRecordsByMonth(@PathVariable int id, @PathVariable int year, @PathVariable int month) {
        logger.debug("getServingRecordsByMonth method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            Map<String, Object> data = new HashMap<>();
            if (year == -1 || month == -1) {
                List<ServiceRecordDto> temp = evaluationService.getRecordsByMid(id, 1, 1, "start desc");
                if (temp.isEmpty()) {
                    result.put("data", null);
                    return result;
                } else {
                    Calendar c = Calendar.getInstance();
                    c.setTimeInMillis(temp.get(0).getStart() * 1000);
                    year = c.get(Calendar.YEAR);
                    month = c.get(Calendar.MONTH);
                }
            }
            List<ServiceRecordDto> records = evaluationService.getRecordsByMonth(id, year, month);
            String preMonth = evaluationService.prevServingMonth(id, year, month);
            String nextMonth = evaluationService.nextServingMonth(id, year, month);
            if (preMonth == null && nextMonth == null && records.isEmpty()) {
                result.put("data", null);
                return result;
            }
            data.put("pre_month", preMonth);
            data.put("next_month", nextMonth);
            data.put("cur_month", String.format("%d %d", year, month));
            data.put("records", records);
            result.put("data", data);
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }

    @RequestMapping(value = "/yuesao/{id}/postHospitals", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getHospitals(@PathVariable int id) {
        logger.debug("getServingRecordsByMonth method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", maternityService.getPostHospitals(id));
        } catch (FailCallException e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", e.getMessage());
            result.put("code", e.getCode());
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }
    @RequestMapping(value = "/yuesao/{id}/trainingSubjects", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getTrainingSubjects(@PathVariable int id) {
        logger.debug("getServingRecordsByMonth method call");
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("success", true);
            result.put("msg", "查询成功");
            result.put("code", 0);
            result.put("data", maternityService.getTrainingSubjects(id));
        } catch (FailCallException e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", e.getMessage());
            result.put("code", e.getCode());
        } catch (Exception e) {
            logger.error(e);
            result.put("success", false);
            result.put("msg", error_message);
            result.put("code", 400);
        }
        return result;
    }
}
